<script lang="ts" setup>
import { watch, ref, computed } from 'vue'
import { useDataCountStore } from '@/store'
import type { Group } from '@/store/modules/dataCount'
import { getDateLocaleString } from '@/utils/common/getDateLocaleString'

const props = defineProps({
  year: {
    type: Number,
    required: true
  }
})

/**
 * @desc 统计数据
 */
const dataCount = ref<{
  group: Group[]
}>({
  group: []
})

/**
 * @desc 基本配置
 */
const MOUTH = {
  'en-US': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
  'zh-CN': [
    '一月',
    '二月',
    '三月',
    '四月',
    '五月',
    '六月',
    '七月',
    '八月',
    '九月',
    '十月',
    '十一月',
    '十二月'
  ]
}
const WEEK = {
  'en-US': ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
  'zh-CN': ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
}

/**
 * @desc 生成假数据
 */
// function createData() {
//   const data: Group[] = []
//   for (let i = 0; i < 53; i++) {
//     data.push({ count: [], baseDate: 666 })
//     for (let j = 0; j < 7; j++) {
//       data[i].count.push(Math.floor(Math.random() * 14))
//     }
//   }
//   return data
// }

const dataCountStore = useDataCountStore()

watch(
  () => props.year,
  () => {
    // dataCount.value.group = createData()
    dataCountStore.addGroup(props.year)
    dataCount.value.group = dataCountStore.$state[props.year]
  },
  { immediate: true }
)

const toolTip = ref({
  visible: false,
  time: 0,
  count: 0,
  position: {
    top: '0',
    left: '0'
  }
})

/**
 * @desc 提示热力图数据
 * @param baseDate 周日时间戳(每列第一格所代表的时间)
 * @param week 一周中的第几天（0-6）
 * @param count 热力值（创建任务数）
 */
function showDate(baseDate: number, week: number, count: number, e: MouseEvent) {
  toolTip.value = {
    visible: true,
    time: baseDate + week * 86400000,
    count,
    position: {
      top: e.y + 'px',
      left: e.x + 'px'
    }
  }
}

/**
 * @desc 隐藏第一列非本年份的热力图数据
 */
const getPreday = computed(() => {
  const firtstDay = new Date(dataCount.value.group[0].baseDate)
  if (firtstDay.getFullYear() != props.year) {
    return new Date(props.year + '').getDay()
  }
  return 0
})

/**
 * @desc 获取热力颜色
 */
function getLevel(count: number) {
  if (count >= 10) return 4
  else if (count >= 5) return 3
  else if (count >= 3) return 2
  else if (count >= 1) return 1
  else return 0
}
</script>

<template>
  <div class="heat-map overflow-x-auto text-center" @mouseout="() => (toolTip.visible = false)">
    <svg width="768" height="112" class="inline" xmlns="http://www.w3.org/2000/svg" version="1.1">
      <g
        v-for="(item, x) of dataCount.group"
        :key="item.baseDate"
        :transform="`translate(${15 + 14 * x}, 16)`"
      >
        <rect
          v-for="(count, y) of item.count"
          v-show="x != 0 || y >= getPreday"
          :key="x * 7 + y"
          width="10"
          height="10"
          :x="14"
          :y="0 + y * 13"
          rx="2"
          ry="2"
          :class="`heatmap-item heatmap-item-level${getLevel(count)}`"
          @mouseover="showDate(item.baseDate, y, count, $event)"
        />
      </g>
      <text
        v-for="(mouth, x) of MOUTH[$i18n.locale as 'en-US' | 'zh-CN']"
        :key="mouth"
        class="block fill-dark-400 text-xs dark:fill-gray-400"
        :x="40 + x * 62"
        y="10"
      >
        {{ mouth }}
      </text>
      <text
        v-for="(day, x) of WEEK[$i18n.locale as 'en-US' | 'zh-CN']"
        :key="day"
        class="block fill-dark-400 text-xs dark:fill-gray-400"
        x="0"
        :y="25 + x * 13"
      >
        {{ day }}
      </text>
    </svg>
  </div>
  <div v-show="toolTip.visible" id="tooltip" class="absolute">
    <p class="mt-1 text-center">
      {{ getDateLocaleString(toolTip.time, $i18n.locale, false) }}
    </p>
    <p class="text-center">
      {{ $t('user.statistical.heatmap.count', toolTip.count) }}
    </p>
  </div>
  <div class="flex justify-center">
    <span>{{ $t('user.statistical.heatmap.less') }}</span>
    <svg height="15" width="70">
      <rect
        v-for="level of [0, 1, 2, 3, 4]"
        :key="level"
        y="4"
        :x="4 + level * 13"
        width="10"
        height="10"
        rx="2"
        ry="2"
        :class="`heatmap-item-level${level}`"
      />
    </svg>
    <span>{{ $t('user.statistical.heatmap.more') }}</span>
  </div>
</template>

<style scoped>
.heat-map::-webkit-scrollbar {
  @apply w-0;
}

.heatmap-item-level0 {
  @apply fill-gray-200 dark:fill-slate-900;
}

.heatmap-item-level1 {
  @apply dark:fill-[#0e4429];

  fill: #39d353;
}

.heatmap-item-level2 {
  @apply dark:fill-[#006d32];

  fill: #26a641;
}

.heatmap-item-level3 {
  @apply dark:fill-[#26a641];

  fill: #006d32;
}

.heatmap-item-level4 {
  @apply dark:fill-[#39d353];

  fill: #0e4429;
}

#tooltip {
  pointer-events: none;
  top: v-bind('toolTip.position.top');
  left: v-bind('toolTip.position.left');
  transform: translateX(-50%) translateY(calc(-100% - 8px));

  @apply px-2 rounded pb-1 text-xs;
  @apply bg-green-50 text-dark-500 dark:(bg-gray-600 text-gray-300);
}

#tooltip::after {
  content: '';
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: transparent;

  @apply absolute left-1/2;
  @apply border-t-green-50 dark:border-t-gray-600 top-full;
}
</style>
